//
//  WNBookVC.swift
//  WalkNovel
//
//  Created by Kevin on 2023/7/6.
//

import UIKit

class WNBookVC: WNBaseVC {
    
    deinit {
        NotificationCenter.default.removeObserver(self, name: WNNotiName.collectNoti, object: nil)
        NotificationCenter.default.removeObserver(self, name: WNNotiName.chapterReadNoti, object: nil)
        NotificationCenter.default.removeObserver(self, name: WNNotiName.loginNoti, object: nil)
    }
    
    lazy var bookBomView: BookBomView = {
        return BookBomView()
    }()
    
    lazy var bookColView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .vertical
        layout.minimumLineSpacing = 0
        let col = UICollectionView.init(frame: .zero, collectionViewLayout: layout)
        col.showsVerticalScrollIndicator = false
        col.showsHorizontalScrollIndicator = false
        col.backgroundColor = .white
        col.delegate = self
        col.dataSource = self
        col.register(BookCoverColCell.self, forCellWithReuseIdentifier: BookCoverColCell.identifier)
        col.register(BookDetailColCell.self, forCellWithReuseIdentifier: BookDetailColCell.identifier)
        col.register(BookListColCell.self, forCellWithReuseIdentifier: BookListColCell.identifier)
        col.register(BookTagColCell.self, forCellWithReuseIdentifier: BookTagColCell.identifier)
        col.register(LibColCell.self, forCellWithReuseIdentifier: LibColCell.identifier)
        col.register(DiscTopReusableView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: TopHeader)
        col.isHidden = true
        return col
    }()
    
    var bookDetailModel: BookDetailModel?
        
    var likeArr = [BookDetailModel]()
        
    var jumpChapterId = ""
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    override func viewConfig() {
        view.addSubview(bookColView)
        view.addSubview(bookBomView)
        bookColView.snp.makeConstraints { make in
            make.top.equalTo(0)
            make.left.right.equalTo(0)
            make.bottom.equalTo(-TabBarTotalHeight)
        }
        bookBomView.snp.makeConstraints { make in
            make.left.bottom.right.equalTo(0)
            make.height.equalTo(TabBarTotalHeight)
        }
        navView.rightBtnImge = "book_rate"
        navView.rightClosure = { [weak self] in
            self?.showRateVC(true, completion: { str in
                
            })
        }
        navView.ishiddRightBtn = true
        navView.backgroundColor = .init(white: 1, alpha: 0)
        view.bringSubviewToFront(navView)
    }
    
    override func dataConfig() {
        pageName = "Book Detail"
        getBookRequest()
        getLikeRequest()
        WNBuriedManager.shared.openBookDetailStart(baseId)
        bookBomView.btnClosure = { [weak self] str in
            if str == "read" {
                self?.wn_pushReadVC(self?.bookDetailModel)
            }else if str == "collect" {
                self?.collectRequest()
            }
        }
    }
    
    override func handleNoti() {
        NotificationCenter.default.addObserver(forName: WNNotiName.collectNoti, object: nil, queue: nil) { [weak self] not in
            if let favorite = not.userInfo?["favorite"] as? Bool {
                self?.bookDetailModel?.favorite = favorite
                self?.bookBomView.model = self?.bookDetailModel
            }
        }
        NotificationCenter.default.addObserver(forName: WNNotiName.chapterReadNoti, object: nil, queue: nil) { [weak self] not in
            if let chapterId = not.userInfo?["chapterId"] as? Int, let chapterName = not.userInfo?["chapterName"] as? String {
                self?.bookDetailModel?.durChapterId = chapterId
                self?.bookDetailModel?.durChapterName = chapterName
                self?.bookBomView.model = self?.bookDetailModel
            }
        }
        NotificationCenter.default.addObserver(forName: WNNotiName.loginNoti, object: nil, queue: nil) { [weak self] not in
            self?.getBookRequest()
            self?.getLikeRequest()
        }
    }
}

extension WNBookVC: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        2
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        section == 0 ? 4 : likeArr.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        if indexPath.section == 0 {
            switch indexPath.item {
            case 0:
                let cell = collectionView.dequeueReusableCell(withReuseIdentifier: BookCoverColCell.identifier, for: indexPath) as! BookCoverColCell
                cell.bookImage.wn_setupImg(bookDetailModel?.coverUrl, placeHolder: "placeholder_cover_ver")
                return cell
            case 1:
                let cell = collectionView.dequeueReusableCell(withReuseIdentifier: BookDetailColCell.identifier, for: indexPath) as! BookDetailColCell
                cell.model = bookDetailModel
                cell.showAllClosure = { [weak self] showAll in
                    self?.bookDetailModel?.showDesAll = showAll                    
                    self?.bookColView.reloadSections(IndexSet(integer: indexPath.section))
                }
                cell.giftBtn.rx.tap.bind { [weak self] in
                    self?.showGiftVC(true, self?.baseId ?? "", completion: { str in
                        self?.wn_toast(str, 2)
                        WNThread.wn_delay(2) {
                            self?.getBookRequest(false)
                        }
                    })
                }.disposed(by: rx.disposeBag)
                return cell
            case 2:
                let cell = collectionView.dequeueReusableCell(withReuseIdentifier: BookListColCell.identifier, for: indexPath) as! BookListColCell
                cell.model = bookDetailModel
                return cell
            case 3:
                let cell = collectionView.dequeueReusableCell(withReuseIdentifier: BookTagColCell.identifier, for: indexPath) as! BookTagColCell
                cell.tagArr = bookDetailModel?.tags ?? [TagsModel]()
                return cell
            default: return UICollectionViewCell()
            }
        }else {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: LibColCell.identifier, for: indexPath) as! LibColCell
            cell.isBookDetail = true
            cell.isHidden = likeArr.count == 0
            cell.model = likeArr[indexPath.item]
            return cell
        }
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        if indexPath.section == 0 {
            if indexPath.item == 0 {
                showCover()
            }
            if indexPath.item == 2 {
                showChapterListVC()
            }
        }else {
            wn_pushBookVC(likeArr[indexPath.item].bookId ?? "")
        }
    }
    
    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        if kind == UICollectionView.elementKindSectionHeader {
            if indexPath.section == 1 {
                let topView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: TopHeader, for: indexPath) as? DiscTopReusableView
                topView?.showBooKLike = true
                return topView!
            }
        }
        return UICollectionReusableView()
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        switch indexPath.section {
        case 0:
            switch indexPath.item {
            case 0: return .init(width: ScreenW, height: scaleWidth(346)+32+NaviTotalHeight)
            case 1: return .init(width: ScreenW, height: (bookDetailModel?.showDesAll ?? true) ? (bookDetailModel?.desOpenH ?? 0)+(bookDetailModel?.otherDetailH ?? 0) : (bookDetailModel?.desCloseH ?? 0)+(bookDetailModel?.otherDetailH ?? 0))
            case 2: return .init(width: ScreenW, height: bookDetailModel?.chapters == 0 ? 0 : 60)
            case 3: return .init(width: ScreenW, height: (bookDetailModel?.tags == nil ? 0 : (bookDetailModel?.tags?.count == 0 ? 0 : 64)))
            default: return .zero
            }
        default:
            return CGSize(width: scaleWidth(100), height: likeArr.count == 0 ? 0 : scaleWidth(144)+42)
        }
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
        return section == 0 ? .zero : .init(width: ScreenW, height: 46)
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return section == 0 ? 0 : (ScreenW-scaleWidth(100)*3-25)*0.5
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return section == 0 ? .zero : .init(top: 0, left: 12, bottom: 12, right: 12)
    }
}

extension WNBookVC: UIScrollViewDelegate {
    
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let offsetY = scrollView.contentOffset.y
        if offsetY <= (scaleWidth(384)+NaviTotalHeight)*0.53 {
            navView.bookDetailModel = nil
            navView.backgroundColor = .init(white: 1, alpha: 0)
        }else {
            navView.bookDetailModel = bookDetailModel
            navView.backgroundColor = .init(white: 1, alpha: abs(offsetY/((scaleWidth(384)))))
        }
    }
    
    func showChapterListVC() {
        let chapterVC = WNChapterVC()
        chapterVC.baseId = baseId
        chapterVC.chapterIdClosure = { [weak self] chapterId in
            self?.wn_pushReadVC(self?.bookDetailModel, "\(chapterId)")
            chapterVC.dismiss(animated: true)
        }
        chapterVC.sheetPosition = .left
        chapterVC.displayPercent = 0.8
        chapterVC.translucentValue = 0.5
        chapterVC.becomeSheet()
        chapterVC.modalPresentationStyle = .overFullScreen
        present(chapterVC, animated: true, completion: nil)
    }
    
    func showCover() {
        if let str = bookDetailModel?.coverUrl, !str.isEmpty {
            let photo = GKPhoto.init()
            photo.url = URL.init(string: str)!
            let browser = GKPhotoBrowser(photos: [photo], currentIndex: 0)
            browser.showStyle = .none
            browser.show(fromVC: self)
        }
    }
}

extension WNBookVC {
    
    func getBookRequest(_ needLoad: Bool = true) {
        if needLoad {
            WNHUD.wn_showLoading()
        }
        provider_book.rx.request(.bookDetail(baseId))
            .asObservable().mapModel(BaseModel<BookDetailModel>.self)
            .subscribe(onNext: { [weak self] (model) in
                self?.bookColView.isHidden = false
                WNHUD.wn_hide()
                guard model.code == 0 else {
                    self?.wn_toast(model.msg ?? "")
                    return
                }
                if let m = model.data {
                    self?.bookDetailModel = m
                    self?.handleRequest()
                }
            }, onError: { [weak self] (error) in
                self?.wn_toast("Check the network connection")
                self?.bookColView.isHidden = false
            }).disposed(by: rx.disposeBag)
    }
    
    func getLikeRequest() {
        provider_discover.rx.request(.guesslike(1))
            .asObservable().mapModel(BaseModel<[BookDetailModel]>.self)
            .subscribe(onNext: { [weak self] (model) in
                guard model.code == 0 else {
                    return
                }
                if let arr = model.data, arr.count > 0 {
                    let fArr = arr.filter({$0.bookId != self?.baseId})
                    self?.likeArr = fArr.count > 6 ? fArr.sample(size: 6)! : fArr
                    self?.bookColView.reloadData()
                }
            }, onError: { (error) in
            }).disposed(by: rx.disposeBag)
    }
    
    func collectRequest() {
        let colType = (bookDetailModel?.favorite ?? true) ? 2 : 1
        provider_book.rx.request(.collect(colType, baseId))
            .asObservable().mapModel(BaseModel<Any>.self)
            .subscribe(onNext: { [weak self] (model) in
                guard model.code == 0 else {
                    self?.wn_toast(model.msg ?? "")
                    return
                }
                if model.data != nil {
                    self?.wn_toast((self?.bookDetailModel?.favorite ?? true) ? "You have removed this book from your Library" : "You have added this book to your Library")
                    self?.bookDetailModel?.favorite = (colType == 1 ? true : false)
                    NotificationCenter.default.post(name: WNNotiName.collectNoti, object: self, userInfo: ["favorite": colType == 1 ? true : false, "bookId": self?.bookDetailModel?.bookId ?? ""])
                }
            }, onError: { [weak self] (error) in
                self?.wn_toast("Check the network connection")
            }).disposed(by: rx.disposeBag)
    }
    
    func handleRequest() {
        bookBomView.model = bookDetailModel
        bookColView.reloadData()
        if !isBlank(jumpChapterId) {
            if jumpChapterId == "-100" {
                WNThread.wn_delay(0.35) {
                    self.wn_pushReadVC(self.bookDetailModel)
                    self.jumpChapterId = ""
                }
            }else if jumpChapterId != "0" {
                WNThread.wn_delay(0.35) {
                    self.wn_pushReadVC(self.bookDetailModel, self.jumpChapterId)
                    self.jumpChapterId = ""
                }
            }
        }
    }
}
